/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 *
 */

import path from 'path';
import { NativeCMakeFiles } from './native-cmake-files';

import { NativeTarget } from './native-codemodel-target.js';
import { NativeLibraryModel } from './native-library-model.js';

export class GenerateNativeLibrary {
  static parseLibrary(abi: string, nativeTarget: NativeTarget, target: string, cmakeFiles?: NativeCMakeFiles) {
    const library = new NativeLibraryModel(nativeTarget.name, nativeTarget.id, nativeTarget.type);
    library.setAbi(abi);
    library.setBuildType(target);
    library.setFolders(this.findFolders(nativeTarget));
    library.setFiles(this.findFiles(nativeTarget));
    library.setOutputs(this.findOutputs(nativeTarget));
    library.setNameOnDisk(nativeTarget.nameOnDisk);
    library.setRuntimeFiles(this.findRuntimeFiles(nativeTarget, cmakeFiles));
    library.setBuild(nativeTarget.paths?.build);
    library.setSource(nativeTarget.paths?.source);
    return library;
  }

  static findFolders(nativeTarget: NativeTarget): string[] {
    const folders: string[] = [];
    nativeTarget.compileGroups?.forEach((group) => {
      group.includes?.forEach((include) => {
        if (include.path) {
          folders.push(include.path);
        }
      });
    });
    return folders;
  }

  private static findFiles(nativeTarget: NativeTarget): string[] {
    const files: string[] = [];
    nativeTarget.sources?.forEach((source) => {
      const sourceGroups = nativeTarget.sourceGroups ?? [];
      const sourceGroup = source.sourceGroupIndex === undefined ? undefined : sourceGroups[source.sourceGroupIndex!];
      if (sourceGroup && sourceGroup.name !== 'Source Files' && source.path) {
        files.push(source.path);
      }
    });
    return files;
  }

  private static findOutputs(nativeTarget: NativeTarget): string[] {
    const outputs: string[] = [];
    nativeTarget.artifacts?.forEach((artifact) => {
      if (artifact.path) {
        outputs.push(artifact.path);
      }
    });
    return outputs;
  }

  private static findRuntimeFiles(nativeTarget: NativeTarget, cmakeFiles?: NativeCMakeFiles): string[] {
    const result: string[] = [];
    let sysroot: string | undefined = nativeTarget.link?.sysroot?.path;
    if (sysroot) {
      sysroot = path.resolve(sysroot);
    }
    nativeTarget.link?.commandFragments?.forEach((fragment) => {
      if (fragment.role !== 'libraries') {
        return;
      }
      let runtimeFile = fragment.fragment;
      if (!runtimeFile) {
        return;
      }
      if (runtimeFile.startsWith('-') || runtimeFile.endsWith('.a')) {
        return;
      }
      if (path.isAbsolute(runtimeFile) && (!sysroot || !runtimeFile.startsWith(sysroot))) {
        result.push(runtimeFile);
        return;
      }

      // cmakeFiles?.paths?.build为正确路径, 为兼容, 保留nativeTarget.paths?.build
      for (const buildDir of [nativeTarget.paths?.build, cmakeFiles?.paths?.build]) {
        if (buildDir) {
          const file = path.join(buildDir, runtimeFile);
          if (sysroot && file.startsWith(sysroot)) {
            continue;
          }
          result.push(file);
        }
      }
    });
    return result;
  }
}
